/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package td3.Vue;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import td3.Modele.Coup;
import td3.Modele.CoupMorpion;
import td3.Modele.Jeu;
import td3.Modele.JeuDeMorpion;
import td3.Modele.JeuDePuissance4;
import td3.Modele.Joueur;
import td3.Modele.JoueurAleatoire;
import td3.Modele.JoueurAleatoireMorpion;
import td3.Modele.JoueurAleatoirePuissance4;
import td3.Modele.JoueurHumain;
import td3.Modele.JoueurHumainMorpion;
import td3.Modele.JoueurHumainPuissance4;
import td3.Modele.Tool;
/**La classe de FenetrePrincipale
 *
 * @author fredericdasilva
 */
public class FenetrePrincipale extends JFrame implements Observer {
    
//    private JPanel fenetrePrincipale;
    private JPanel grilleJeu;
    private JPanel colonneBouton;
    JButton bouton1;
    JButton bouton2;
    private JMenuBar menu;
    JMenu partie;
    JMenu niveauCPU;
    JMenu aide;
    
    JMenuItem nouveau; //les sous-menus
    JMenuItem charger;
    JMenuItem Sauvegarder_Sous;
    JMenuItem help;
    JMenuItem nivAleatoire;
    JMenuItem nivBon;
    
    JMenuItem fermer;
    
    JTextField champ1, champ2;
    //    private Toolkit tk;
    public FenetrePrincipale.Cases[][] tab;
    public JLabel[] labels = new JLabel[3];
    Jeu j;
    File fichierSauvegarde;
    private boolean etatSauvegarde;
    
    /** Constructeur d'une fenêtre principale en fonction du jeu, donné en paramètre
     *
     * @param jeu  un Jeu
     */
    public FenetrePrincipale( Jeu jeu) {
        
        super();
        this.j = jeu;
        // Le jeu observe la fenêtre
        j.addObserver(this);
        int n = jeu.P.largeur;
        int nn = jeu.P.longueur;
        construireFenetre(n, nn);
        fichierSauvegarde = null;
        initMenu();
        setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
    }
    /** Permet de mettre à jour la fenêtre à chaque variation de la grille du jeu
     *
     * @param o un Observable
     * @param _c un Objet
     */
    @Override
    public void update(Observable o, Object _c) {
        Coup c=(Coup)_c;
        if (j instanceof JeuDePuissance4){
            int p=0;
            
            
            while (p<c.x){
                
                if (j.P.etatIdPlateau[c.x][c.y] == j.J1.getId()) {
                    tab[p][c.y].setBackground(Color.yellow);
                }
                if (j.P.etatIdPlateau[c.x][c.y] == j.J2.getId()) {
                    tab[p][c.y].setBackground(Color.red);
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
                tab[p][c.y].setBackground(Color.black);
                p++;
            }
            if(!j.partieTerminee()) {
                labels[0].setText("A "+(j.joueurSuivant()).getName()+" de jouer.");
                labels[1].setText(""+(j.quelleJoueur(j.P.joueurencours)).getName()+" en cours de JEU.");
                labels[2].setText("TOTAL: "+j.P.nbCoups+" Coups Joués ");
                
            }
            if (j.partieTerminee()){
                labels[0].setText(j.quiStringAGagne());
                labels[1].setText(""+(j.quelleJoueur(j.P.joueurencours)).getName()+" en cours de JEU.");
                labels[2].setText("TOTAL: "+j.P.nbCoups+" Coups Joués " );
                
            }
            tab[c.x][c.y].mettreCouleur(c.x, c.y);}
        if (j instanceof JeuDeMorpion){
            if(!j.partieTerminee()) {
                labels[0].setText("A "+(j.joueurSuivant()).getName()+" de jouer.");
                labels[1].setText(""+(j.quelleJoueur(j.P.joueurencours)).getName()+" en cours de JEU.");
                labels[2].setText("TOTAL: "+j.P.nbCoups+" Coups Joués ");
                
            }
            if (j.partieTerminee()){
                labels[0].setText(j.quiStringAGagne());
                labels[1].setText(""+(j.quelleJoueur(j.P.joueurencours)).getName()+" en cours de JEU.");
                labels[2].setText("TOTAL: "+j.P.nbCoups+" Coups Joués " );
                
            }
            if(j.partieTerminee()){
                labels[1].setText("------- PARTIE FINIE ------- ");
                labels[2].setText("TOTAL: "+j.P.nbCoups+" Coups Joués " );
                
                
            }
            tab[c.x][c.y].mettreCouleur(c.x, c.y);
        }
    }
    /** Permet de construire la fenêtre de nombre de colonne nn, et de nombre de ligne n
     *
     * @param n un entier
     * @param nn un entier
     */
    private void construireFenetre(int n, int nn) {
        //        tk = Toolkit.getDefaultToolkit();
        //        Dimension screenSize = tk.getScreenSize();
        this.setTitle("FENETRE GRAPHIQUE");
        //        this.setSize(new Dimension(2*screenSize.width/3,3*screenSize.height/4));
        this.setSize(900, 700);
        this.setLocationRelativeTo(null);
        
        Container c = this.getContentPane();
        
        
        
        /////// FENETRE ET AUTRES /////////////////////
        
        
        grilleJeu = new JPanel();
        colonneBouton = new JPanel();
        
        BorderLayout dispositionFenetre = new BorderLayout();
        GridLayout dispositionGrille = new GridLayout(nn, n);
        FlowLayout dispositionBouton = new FlowLayout();
        
        //Ajouter de la fenetre principale
        c.setLayout(dispositionFenetre);
        //Ajouter la grille de jeu
        grilleJeu.setLayout(dispositionGrille);
        
        //Creation du tableau de CASE
        tab = new FenetrePrincipale.Cases[nn][n];
        
        //Construction de la Grille
        for (int i = 0; i < nn; i++) {
            for (int z = 0; z < n; z++) {
                FenetrePrincipale.Cases pan = new FenetrePrincipale.Cases(i, z);
                tab[i][z] = pan;
                
                pan.setBorder(BorderFactory.createLineBorder(Color.white, 2));
                grilleJeu.add(pan);
            }
        }
        
        TitledBorder t = BorderFactory.createTitledBorder("Grille de Jeu");
        grilleJeu.setBorder(t);
        c.add(grilleJeu);
        
        //Ajouter les boutons
        bouton1 = new JButton("Jouer");
        bouton2 = new JButton("Recommencer");
        
        bouton2.addActionListener(new Recommencer());
        bouton1.addActionListener(new Jouer());
        
        JPanel etatJeu = new JPanel(new GridLayout(0,1));
        
        
        labels[0]  = new JLabel("A "+j.J1.getName()+" de jouer.",SwingConstants.CENTER);
        labels[1]  = new JLabel("----------------",SwingConstants.CENTER);
        labels[2]  = new JLabel("TOTAL: "+j.P.nbCoups+" Coups Joués ",SwingConstants.CENTER );
        
        for (int i = 0; i < labels.length; i++) {
            etatJeu.add(labels[i]);
        }
        
        champ1 = new JTextField();
        champ1.setText("");
        TitledBorder nomJoueur = BorderFactory.createTitledBorder("Joueur 1");
        champ1.setBorder(nomJoueur);
        etatJeu.add(champ1);
        champ1.setPreferredSize(new Dimension(colonneBouton.getWidth()/10,etatJeu.getHeight()/10));
        champ2 = new JTextField();
        champ2.setText("");
        TitledBorder nomJoueur2 = BorderFactory.createTitledBorder("Joueur 2: ");
        champ2.setBorder(nomJoueur2);
        etatJeu.add(champ2);
        champ2.setPreferredSize(new Dimension(colonneBouton.getWidth()/10,etatJeu.getHeight()/10));
        
        //Espace entre mes 2 boutons
        colonneBouton.setLayout(new BorderLayout());
        colonneBouton.add(bouton1, BorderLayout.NORTH);
        colonneBouton.add(bouton2,"South");
        
        colonneBouton.add(etatJeu);
        colonneBouton.setBackground(Color.lightGray);
        c.add(colonneBouton, BorderLayout.EAST);
        
        TitledBorder d = BorderFactory.createTitledBorder("Info & Actions");
        colonneBouton.setBorder(d);
        colonneBouton.setPreferredSize(new Dimension(this.getWidth()/4,20));
        //Finaliser la fenètre.
        
        grilleJeu.setBackground(Color.lightGray);
    }
    
    /** Permet d'initialiser la barre de menu de la fenêtre
     *
     */
    private void initMenu(){
        ///// AJOUT DES MENUS ////////
        menu = new JMenuBar(); //Creation de la barre de menu
        
        partie = new JMenu("Partie"); //les titres de menu
        niveauCPU = new JMenu("Niveau CPU MORPION");
        aide = new JMenu("Aide");
        
        nouveau = new JMenuItem("Nouvelle Partie"); //les sous-menus
        help = new JMenuItem("Aide");
        fermer = new JMenuItem("Fermer");
        charger = new JMenuItem("Charger Partie");
        Sauvegarder_Sous = new JMenuItem("Sauvegarder Partie Sous");
        nivAleatoire = new JMenuItem("CPU Aléatoire");
        nivBon = new JMenuItem("CPU Niveau 1");

        
        partie.add(nouveau); //Ajout des sous-menus aux menus
        partie.addSeparator(); //Ajout de Séparateur
        partie.add(charger);
        partie.addSeparator(); //Ajout de Séparateur
        partie.add(Sauvegarder_Sous);
        partie.addSeparator(); //Ajout de Séparateur
        partie.add(fermer);
        niveauCPU.add(nivAleatoire);
        niveauCPU.addSeparator(); //Ajout de Séparateur
        niveauCPU.add(nivBon);
        aide.add(help);
        
        charger.setEnabled(false);
        Sauvegarder_Sous.setEnabled(false);
        
        nouveau.addActionListener(new NouvellePartie());
        fermer.addActionListener(new Fermer());
        Sauvegarder_Sous.addActionListener(new Sauvegarder_Sous());
        charger.addActionListener(new charger());
        help.addActionListener(new Aide());
        nivAleatoire.addActionListener(new Aleatoire());
        nivBon.addActionListener(new Niveau1());

        champ1.setEditable(false);
        champ2.setEditable(false);
        
        menu.add(partie);
        menu.add(niveauCPU);
        menu.add(aide);
        
        setJMenuBar(menu);
    }
    
    /** Rajoute un écouteur sur chaque case de la grille
     *
     * @param nn entier
     * @param n  entier
     */
    public void ecouteur(int nn,int n){
        for (int i = 0; i < nn; i++) {
            for (int z = 0; z < n; z++) {
                tab[i][z].addMouseListener(tab[i][z]);
                
            }
        }
    }
    /** La classe NouvellePartie gère les clics sur le menu correspondant
     *
     *
     */
    class NouvellePartie implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            dispose();
            champ1.setEditable(false);
            champ2.setEditable(false);
            
            j.arreter();
            
            FenetreAccueil1 Fen = new FenetreAccueil1();
            Fen.setLocationRelativeTo(null);
            Fen.setVisible(true);
            System.gc();
            
        }
    }
    
    class Aleatoire implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            niveauCPU.setEnabled(false);
        }
    }
    
     class Niveau1 implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            if (j.J1 instanceof JoueurAleatoire){
               j.J1.hardCPU=true;
            }
            if (j.J2 instanceof JoueurAleatoire){
                j.J2.hardCPU=true;
                
            }
            niveauCPU.setEnabled(false);
        }
    }
    
     
    class Aide implements ActionListener {
        
        @Override
        public void actionPerformed(ActionEvent e) {
            if (j instanceof JeuDeMorpion){
				JOptionPane.showMessageDialog(grilleJeu,"BRAVO!!!!!!!!!    Vous avez choisi de jouer au MORPION\n"+ 
		"\nPour gagner, vous devez aligner 3 pions sur la grille.\n"+
                "Pour charger une partie, il faut d'abord cliquer sur \"JOUER\""+
		"pour démarrer, et cliquer \"CHARGER\".\n"+  
                "Pour sauvegarder une partie, il faut cliquer sur \"SAUVEGARDER SOUS\""+
		"puis choisir le dossier de destination.\n"+                        
		"Pour démarrer la partie, cliquez sur \"JOUER\"\n"+
		"\nUne fois la partie terminée, vous pouvez rejouer en cliquant \"RECOMMENCER\".\n"+
		"\nLe choix d'une NOUVELLE PARTIE dans le menu \"PARTIE\"\n"+
		"vous ramène à la fenêtre d'accueil","LIRE ATTENTIVEMENT", JOptionPane.INFORMATION_MESSAGE);
                                
            }	
            if (j instanceof JeuDePuissance4){
				JOptionPane.showMessageDialog(grilleJeu,"Bravo!!!!!!!!!    Vous avez choisi de jouer au PUISSANCE 4\n"+ 
		"\nPour gagner, vous devez aligner 4 pions sur la grille.\n"+
		"Pour démarrer la partie, cliquez sur \"JOUER\".\n"+
		"\nUne fois la partie terminée, vous pouvez rejouer en cliquant \"RECOMMENCER\".\n"+
		"\nLe choix d'une NOUVELLE PARTIE dans le menu \"PARTIE\"\n"+
		"vous ramène à la fenêtre d'accueil","LIRE ATTENTIVEMENT", JOptionPane.INFORMATION_MESSAGE);
                                
            }
        }
        
    }
    /** La classe Recommencer gère les clics sur le bouton Recommencer
     *
     *
     */
    class Recommencer implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            
            j.arreter(); //Arreter du processus en cours au niveau de la grille
            dispose();
            
            int a = Tool.monRandom(56,100);
            int b = Tool.monRandom(1,55);
            Joueur jojo = new JoueurHumainMorpion(a,j.J1.getName());
            Joueur jaja = new JoueurAleatoireMorpion(a,j.J2.getName());
            if (j.J1 instanceof JoueurHumainMorpion){
                jojo = new JoueurHumainMorpion(a,j.J1.getName());
            }
            if (j.J1 instanceof JoueurAleatoireMorpion){
                jojo = new JoueurAleatoireMorpion(a,j.J1.getName());
            }
            if (j.J2 instanceof JoueurHumainMorpion){
                jaja = new JoueurHumainMorpion(b,j.J2.getName());
            }
            if (j.J2 instanceof JoueurAleatoireMorpion){
                jaja = new JoueurAleatoireMorpion(b,j.J2.getName());
            }
            if (j.J1 instanceof JoueurHumainPuissance4){
                jojo = new JoueurHumainPuissance4(a,j.J1.getName());
            }
            if (j.J1 instanceof JoueurAleatoirePuissance4){
                jojo = new JoueurAleatoirePuissance4(a,j.J1.getName());
            }
            if (j.J2 instanceof JoueurHumainPuissance4){
                jaja = new JoueurHumainPuissance4(b,j.J2.getName());
            }
            if (j.J2 instanceof JoueurAleatoirePuissance4){
                jaja = new JoueurAleatoirePuissance4(b,j.J2.getName());
            }
            
            Jeu jeu = new JeuDeMorpion(jojo,jaja);
            if (j instanceof JeuDeMorpion){
                jeu = new JeuDeMorpion(jojo,jaja);}
            if (j instanceof JeuDePuissance4){
                jeu = new JeuDePuissance4(jojo,jaja);}
            FenetrePrincipale f = new FenetrePrincipale(jeu);
            f.champ1.setText(j.J1.getName());
            f.champ2.setText(j.J2.getName());
            f.bouton2.setEnabled(false);
            f.nouveau.setEnabled(false);
            niveauCPU.setEnabled(true);
            f.charger.setEnabled(false);
            f.Sauvegarder_Sous.setEnabled(false);
            

            System.gc();
            
            //                Thread m = new Thread (jeu);
            //                m.start();
            
            
        }
    }
    
    /** La classe Fermer gère les clics sur le menu Fermer
     *
     *
     */
    class Fermer implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            
            System.gc();
            System.exit(0);
        }
    }
    /** La classe Jouer gère les clics sur le bouton Jouer
     *
     *
     */
    class Jouer implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {   
        nouveau.setEnabled(true);
        Sauvegarder_Sous.setEnabled(true);
        charger.setEnabled(true);
        bouton2.setEnabled(true);
        bouton1.setEnabled(false);
        niveauCPU.setEnabled(false);
        Thread p = new Thread (j);
        if (j.J1 instanceof JoueurHumain || j.J2 instanceof JoueurHumain){
                ecouteur(j.P.longueur,j.P.largeur);
        }
        p.start();
        
        }
    }
    class Sauvegarder implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }

    class Sauvegarder_Sous implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("On va sauvegarder");
            try {
                actionEnregistrerSous();
            } catch (InterruptedException ex) {
                Logger.getLogger(FenetrePrincipale.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    class charger implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            actionCharger();
        }
    }
  
    private void actionEnregistrerSous() throws InterruptedException {          
        // Permet de rester dans le même fichier lors de sauvegarde multiple
        System.out.println("hello");
        this.j.mise_en_attente();
        String chemin = (fichierSauvegarde == null ? null : fichierSauvegarde.getParent());

        // On créé le file chooser pour des fichier d'extension .env
        JFileChooser choixFichier = new JFileChooser(chemin);
        choixFichier.setFileFilter(new FileNameExtensionFilter("Fichiers Environement", "env"));

        // On affiche le file chooser et on récupère quel bouton a été cliqué
        int retour = choixFichier.showSaveDialog(this);

        // Si l'utilisateur a choisi l'option sauvegarder
        if (retour == JFileChooser.APPROVE_OPTION) {
            // On récupère le fichier qu'il a choisi
            fichierSauvegarde = choixFichier.getSelectedFile();
            boolean okEnregistrement = true;
            //Si le fichier existe déjà
            if (fichierSauvegarde.exists()) {

                // Pop-up de Confirmation
                if (JOptionPane.showOptionDialog(this,
                        "Êtes-vous sur de vouloir écraser ce fichier?",
                        "Confirmation",
                        JOptionPane.YES_NO_OPTION,
                        JOptionPane.QUESTION_MESSAGE,
                        null, null, null) == JOptionPane.NO_OPTION) {
                    // Si l'utilisateur ne veut pas écraser:
                    okEnregistrement = false;
                }
            }
            if (okEnregistrement) {
                // Si c'est ok on l'enregistre
                actionEnregistrer();
                this.j.reprise();
            } else {
                // Sinon on repropose d'enregistrer
                actionEnregistrerSous();
            }
        }
        else this.j.reprise();
    }


//    private void actionEnregistrer() {
//        //On arrête le thread de calcul si il a été lancé
//        if (threadCalcul.isAlive()) {
//            stopThreadCalcul();
//        }
//        if (fichierSauvegarde == null) {//si on a pas encore de chemin de sauvegarde on fait appel a enregistrerSous
//            actionEnregistrerSous();
//        } else {// Sinon on sauvegarde directement
//
//            FileOutputStream fos = null;
//            ObjectOutputStream oos = null;
//            try {
//                System.out.println("J'enregistre:" + fichierSauvegarde);
//                fos = new FileOutputStream(fichierSauvegarde);
//                oos = new ObjectOutputStream(fos);
//                oos.writeObject(myEnv.versionSimplifiee());
//            } catch (FileNotFoundException ex) {
//                System.out.println("Fichier non trouvé lors de l'enregistrement");
//            } catch (IOException ex) {
//                System.out.println("Erreur lors de l'enregistrement");
//            } finally {
//
//                try {
//                    if (oos != null) {
//                        oos.close();
//                    }
//                } catch (IOException ex) {
//                    Logger.getLogger(Fenetre.class.getName()).log(Level.SEVERE, null, ex);
//                }
//                try {
//                    if (fos != null) {
//                        fos.close();
//                    }
//                } catch (IOException ex) {
//                    Logger.getLogger(Fenetre.class.getName()).log(Level.SEVERE, null, ex);
//                }
//            }
//        }
//        etatSauvegarde = true;
//    }

    private void actionEnregistrer() throws InterruptedException {
        //On arrête le thread de calcul si il a été lancé
 
        System.out.println("dans le enregistrer");
        if (fichierSauvegarde == null) {//si on a pas encore de chemin de sauvegarde on fait appel a enregistrerSous
            actionEnregistrerSous();
        } else {// Sinon on sauvegarde directement

            FileOutputStream fos = null;
            ObjectOutputStream oos = null;
            try {
                System.out.println("J'enregistre:" + fichierSauvegarde);
                fos = new FileOutputStream(fichierSauvegarde);
                oos = new ObjectOutputStream(fos);
                //sauvegarde de la grille
                
                //sauvegarde des joueurs
                
                //sauvegarde du type de jeu
                
                //oos.writeObject(myEnv.versionSimplifiee());
                
                
                Enregistrement e = new Enregistrement();
                e.id1 =this.j.J1.getId();
                e.id2=this.j.J2.getId();
                e.name1=this.j.J1.getName();
                e.name2=this.j.J2.getName();
                e.plateau=j.P.etatIdPlateau;
                e.joueurencours=j.P.joueurencours;
                e.largeur=j.P.largeur;
                e.longueur=j.P.longueur;
                e.nbCoups=j.P.nbCoups;
                if ((j.J1 instanceof JoueurAleatoire) && (j.J2 instanceof JoueurAleatoire)){
                    e.CPU=0;
                }
                else if (j.J2 instanceof JoueurAleatoire){
                    e.CPU=1;
                }
                else { e.CPU=2;
                    
                }
                if (j instanceof JeuDeMorpion){
                    e.typejeu=1;
                }
                if (j instanceof JeuDePuissance4){
                    e.typejeu=2;
                }
                e.nivoCPU1=this.j.J1.hardCPU;
                e.nivoCPU2=this.j.J2.hardCPU;
                
                        
                //Object l2=(Object)this.j.P.
                
                oos.writeObject(e);
            } catch (FileNotFoundException ex) {
                System.out.println("Fichier non trouvé lors de l'enregistrement");
            } catch (IOException ex) {
                System.out.println("Erreur lors de l'enregistrement");
            } finally {

                try {
                    if (oos != null) {
                        oos.close();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(FenetrePrincipale.class.getName()).log(Level.SEVERE, null, ex);
                }
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException ex) {
                   Logger.getLogger(FenetrePrincipale.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        etatSauvegarde = true;
    }

    private void actionCharger() {
        
        this.j.mise_en_attente();
        // Permet de rester dans le même fichier
        String chemin = (fichierSauvegarde == null ? null : fichierSauvegarde.getParent());

        // On crée le file chooser pour des fichier d'extension .env
        JFileChooser choixFichier = new JFileChooser(chemin);
        choixFichier.setFileFilter(new FileNameExtensionFilter("Fichiers Environement", "env"));

        // On affiche le file chooser et on récupère quel bouton a été cliqué
        int retour = choixFichier.showOpenDialog(this);

        // Si l'utilisateur a validé
        if (retour == JFileChooser.APPROVE_OPTION) {


            FileInputStream fis = null;
            ObjectInputStream ois = null;
            try {
                // On récupère le fichier qu'il a choisi
                fichierSauvegarde = choixFichier.getSelectedFile();

                //on créé les flux nécessaire a la lecture
                fis = new FileInputStream(fichierSauvegarde);
                ois = new ObjectInputStream(fis);

                // On récupère les données stockées
                Enregistrement l =(Enregistrement)ois.readObject();
                        
                j.arreter(); //Arreter du processus en cours au niveau de la grille
                dispose();
            
            
            Joueur jojo = new JoueurHumainMorpion(l.id1,l.name1);
            Joueur jaja = new JoueurAleatoireMorpion(l.id2,l.name2);
            if ((l.CPU==1 || l.CPU==2) && l.typejeu==1){
                jojo = new JoueurHumainMorpion(l.id1,l.name1);
            }
            if ((l.CPU==0) && l.typejeu==1){
                jojo = new JoueurAleatoireMorpion(l.id1,l.name1);
                jojo.hardCPU=l.nivoCPU1;
            }
            if ((l.CPU==2) && l.typejeu==1){
                jaja = new JoueurHumainMorpion(l.id2,l.name2);
            }
            if ((l.CPU==0 || l.CPU==1) && l.typejeu==1){
                jaja = new JoueurAleatoireMorpion(l.id2,l.name2);
                jaja.hardCPU=l.nivoCPU2;
            }
            if ((l.CPU==1 || l.CPU==2) && l.typejeu==2){
                jojo = new JoueurHumainPuissance4(l.id1,l.name1);
            }
            if ((l.CPU==0) && l.typejeu==2){
                jojo = new JoueurAleatoirePuissance4(l.id1,l.name1);
            }
            if ((l.CPU==2) && l.typejeu==2){
                jaja = new JoueurHumainPuissance4(l.id2,l.name2);
            }
            if ((l.CPU==0 || l.CPU==1) && l.typejeu==2){
                jaja = new JoueurAleatoirePuissance4(l.id2,l.name2);
            }
            
            Jeu jeu = new JeuDeMorpion(jojo,jaja);
            if (l.typejeu==1){
                jeu = new JeuDeMorpion(jojo,jaja);}
            if (l.typejeu==2){
                jeu = new JeuDePuissance4(jojo,jaja);}
            FenetrePrincipale f = new FenetrePrincipale(jeu);
            for(int i=0; i< f.j.P.longueur ; i++){
                    for(int k=0; k < f.j.P.largeur; k++){
                        f.tab[i][k].setBackground(Color.black);
                        f.j.P.etatIdPlateau=l.plateau;
                        if(f.j.P.etatIdPlateau[i][k]!=0) {
                            f.tab[i][k].mettreCouleur(i,k);
                        }
                    }
                }
            f.j.P.joueurencours=l.joueurencours;
            f.j.P.nbCoups=l.nbCoups;
            f.champ1.setText(l.name1);
            f.champ2.setText(l.name2);
            f.bouton2.setEnabled(false);
            f.nouveau.setEnabled(false);
            niveauCPU.setEnabled(false);
            f.charger.setEnabled(false);
            f.Sauvegarder_Sous.setEnabled(false);
            

            System.gc();
                  
                
            } catch (ClassNotFoundException ex) {
                System.out.println("Problème de conversion lors de l'ouverture");
            } catch (FileNotFoundException ex) {
                System.out.println("Fichier non trouvé lors de l'ouverture");

            } catch (IOException ex) {
                System.out.println("Erreur lors de l'ouverture: " + ex.getLocalizedMessage());
            } finally {
                try {
                    if (ois != null) {
                        ois.close();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(FenetrePrincipale.class.getName()).log(Level.SEVERE, null, ex);
                }
                try {
                    if (fis != null) {
                        fis.close();
//                        this.j.reprise();
                        
                    }
                } catch (IOException ex) {
                    Logger.getLogger(FenetrePrincipale.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        else this.j.reprise();
    }
    
    //    }
    ////////////////  CLASSE CASE //////////////////////////////////////
    
    
    /**
     *
     */
    public class Cases extends JPanel implements ActionListener {
        
        public int ligne;
        
        public int colonne;
        
        /** Constructeur de case(i,j) i = ligne, j = colonne
         *
         * @param ligne entier
         * @param colonne colonne
         */
        public Cases(final int ligne, final int colonne) {
            super();
            this.ligne = ligne;
            this.colonne = colonne;
            setBackground(Color.black);
        }
        
       
        @Override
        public void actionPerformed(ActionEvent e) {
            
        }
        
        /** Colorier la case de coordonnée ligne et colonne de la fenêtre
         *
         * @param ligne entier
         * @param colonne entier
         */
        public void mettreCouleur(int ligne, int colonne) {
            
            
            if (j.P.etatIdPlateau[ligne][colonne] == j.J1.getId()) {
                
                tab[ligne][colonne].setBackground(Color.yellow);
            }
            if (j.P.etatIdPlateau[ligne][colonne] == j.J2.getId()) {
                tab[ligne][colonne].setBackground(Color.red);
            }
            
            
        }
        /** Permet de rajouter un écouteur sur la case fournie en paramètre
         *
         * @param aThis Case
         */
        public void addMouseListener(Cases aThis) {
            addMouseListener(new MouseAdapter() {
                @Override
                
                public void mouseClicked(MouseEvent e){
                    
                    if (j.J1 instanceof JoueurHumain || j.J2 instanceof JoueurHumain)
                    {
                        Coup c = new CoupMorpion(0,0);
                        c.x=ligne;
                        c.y=colonne;
                        
                        
                        Joueur retour;
                        
                        if (!j.partieTerminee()&&!j.AGagne()){
                            
                            retour = j.joueurSuivant();
                            
                            
                            if (j.coupPossible(c)){
                                labels[0].setText("A "+j.quelleJoueur(j.P.joueurencours).getName()+" de jouer.");
                                labels[1].setText(""+j.joueurSuivant().getName()+" en cours de JEU.");
                                labels[2].setText("TOTAL: "+j.P.nbCoups+" Coups Joués " );
                                
                                j.jouerCoupJeuJoueurHumain(c, retour.getId());
                                
                                System.out.println(j.P.toString());
                                System.out.println(j.P.nbCoups+" Coups joués");
                                
                                
                                
                            }
                            
                        }
                        if (j.partieTerminee()){
                            labels[1].setText("------- PARTIE FINIE ------- ");
                            labels[2].setText("TOTAL: "+j.P.nbCoups+" Coups Joués " );
                        }
                        
                    }
                }
                
            });
        }
    }
}
